From: Paul Donald Date: Tue, 28 Oct 2025 18:28:42 +0000 (+0100) Subject: router: Rewrite the ingress MTU to one configured for the interface X-Git-Url: http://git.openwrt.org/%22https:/collectd.org//%22/%22https:/collectd.org/%22?a=commitdiff_plain;h=b9a071b8341fbaa2d518df6b45286b1a822845ee;p=project%2Fodhcpd.git router: Rewrite the ingress MTU to one configured for the interface There are edge cases where routers forward ICMPv6 RA which contain an MTU which is too large/small for the receiving client. Override the ingress MTU with the value configured on the interface. Signed-off-by: Paul Donald Link: https://github.com/openwrt/odhcpd/pull/296 Signed-off-by: Álvaro Fernández Rojas --- diff --git a/src/router.c b/src/router.c index 82d3187..9b482d2 100644 --- a/src/router.c +++ b/src/router.c @@ -1089,19 +1089,34 @@ static void forward_router_advertisement(const struct interface *iface, uint8_t uint8_t *mac_ptr = NULL; struct in6_addr *dns_ptr = NULL; size_t dns_count = 0; + // MTU option + struct nd_opt_mtu *mtu_opt = NULL; + uint32_t ingress_mtu_val = 0; + /* Parse existing options */ icmpv6_for_each_option(opt, &adv[1], end) { - if (opt->type == ND_OPT_SOURCE_LINKADDR) { - /* Store address of source MAC-address */ + switch (opt->type) { + case ND_OPT_SOURCE_LINKADDR: mac_ptr = opt->data; - } else if (opt->type == ND_OPT_RECURSIVE_DNS && opt->len > 1) { - /* Check if we have to rewrite DNS */ - dns_ptr = (struct in6_addr*)&opt->data[6]; - dns_count = (opt->len - 1) / 2; + break; + + case ND_OPT_RECURSIVE_DNS: + if (opt->len > 1) { + dns_ptr = (struct in6_addr *)&opt->data[6]; + dns_count = (opt->len - 1) / 2; + } + break; + + case ND_OPT_MTU: + if (opt->len == 1 && (uint8_t *)opt + sizeof(struct nd_opt_mtu) <= end) { + mtu_opt = (struct nd_opt_mtu *)opt; + ingress_mtu_val = ntohl(mtu_opt->nd_opt_mtu_mtu); + } + break; } } - notice("Got a RA on %s", iface->name); + info("Got a RA on %s", iface->name); /* Indicate a proxy, however we don't follow the rest of RFC 4389 yet */ adv->nd_ra_flags_reserved |= ND_RA_FLAG_PROXY; @@ -1140,8 +1155,16 @@ static void forward_router_advertisement(const struct interface *iface, uint8_t } } - notice("Forward a RA on %s", c->name); + /* Rewrite MTU option if local RA MTU is configured */ + if (c->ra_mtu && mtu_opt) { + if (ingress_mtu_val != c->ra_mtu) { + debug("Rewriting RA MTU from %u to %u on %s", + ingress_mtu_val, c->ra_mtu, c->name); + mtu_opt->nd_opt_mtu_mtu = htonl(c->ra_mtu); + } + } + info("Forward a RA on %s", c->name); odhcpd_send(c->router_event.uloop.fd, &all_nodes, &iov, 1, c); } }